#include "../utils.hpp"

float vertices[] = {
    // 位置          // 颜色
    -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, -0.05f, -0.05f, 0.0f, 0.0f, 1.0f,

    -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, 0.05f,  0.05f,  0.0f, 1.0f, 1.0f};

// 当前路径
#define SOURCE_PATH ROOT_SOURCE_PATH "/src/core/instance_array/"

unsigned int VAO, VBO;
std::shared_ptr<Shader> instanceShader;

void init()
{
    instanceShader = std::make_shared<Shader>(SOURCE_PATH "test.vert", SOURCE_PATH "test.frag", nullptr);
    instanceShader->enable();

    // 启用深度测试
    glEnable(GL_DEPTH_TEST);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    // 创建顶点数组对象和缓冲区对象
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(2 * sizeof(float)));
    glEnableVertexAttribArray(1);

    // 创建偏移数组
    Vec2f translations[100];
    int index = 0;
    float offset = 0.1f;
    for (int y = -10; y < 10; y += 2)
    {
        for (int x = -10; x < 10; x += 2)
        {
            Vec2f translation;
            translation.x() = (float)x / 10.0f + offset;
            translation.y() = (float)y / 10.0f + offset;
            translations[index++] = translation;
        }
    }

    // 创建并绑定实例数组
    unsigned int Ins;
    glGenBuffers(1, &Ins);
    glBindBuffer(GL_ARRAY_BUFFER, Ins);

    // 传入实例数组，并制定属性内存布局
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vec2f) * 100, translations, GL_STATIC_DRAW);

    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (void *)0);

    // 指定 2 号属性对应实例数组，每渲染 1 个实例就更新到下一个数据
    glVertexAttribDivisor(2, 1);
}

void render()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // 绘制 100 个实例化对象
    glBindVertexArray(VAO);
    glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 100);
}

int main()
{
    GLFWwindow *window = initProgram();
    if (window == nullptr)
        return -1;

    // 创建顶点数据
    init();

    // 开启消息循环
    while (!glfwWindowShouldClose(window))
    {
        // 渲染指令
        render();

        // 交换缓冲，处理并调用事件
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // 销毁资源
    glfwTerminate();

    return 0;
}